﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TjZheng.Framework;
using TjZheng.News.Business;
using TjZheng.News.DataEntity;
using TjZheng.Cache;
using System.Web;
using TjZheng.Base;

namespace TjZheng.News.Process
{
    public partial class ArticleInfoProcess
    {
        /// <summary>
        /// 获取评论列表
        /// </summary>
        /// <param name="categoryId"></param>
        /// <param name="articleId"></param>
        /// <param name="commentID"></param>
        /// <param name="position"></param>
        /// <param name="loadCount"></param>
        /// <param name="isLoadFloor"></param>
        /// <returns></returns>
        public virtual InvokeResult GetCommentList(int? categoryId, int? articleId, int? commentID, string position, int? loadCount = 10, int? isLoadFloor = 0)
        {
            InvokeResult objInvokeResult = new InvokeResult();
            if (!categoryId.HasValue)
            {
                objInvokeResult.ResultCode = "CategoryIdEmpty";
                objInvokeResult.ResultMessage = "CategoryId不存在";
                return objInvokeResult;
            }
            if (!articleId.HasValue)
            {
                objInvokeResult.ResultCode = "ArticleIdEmpty";
                objInvokeResult.ResultMessage = "ArticleId不存在";
                return objInvokeResult;
            }
            if (!ExistTableCommentInfo(categoryId.Value))
            {
                objInvokeResult.ResultCode = "TableEmpty";
                objInvokeResult.ResultMessage = "评论表不存在";
                return objInvokeResult;
            }
            if (!loadCount.HasValue || loadCount <= 0 || loadCount > 20)
            {
                loadCount = 10;
            }
            BizCommentInfo objBizCommentInfo = new BizCommentInfo(categoryId.Value.ToString());
            List<CommentInfo> objCommentInfoList = null;
            int recordCount = 0;
            if (commentID.HasValue)
            {
                if (position == "top")
                {
                    objCommentInfoList = objBizCommentInfo.GetListCache("", TimeSpan.FromSeconds(10), "ObjectId='" + articleId + "' AND IsRelease=1 AND CommentId>" + commentID, "CommentId asc", "top " + loadCount + " *");
                }
                else
                {
                    objCommentInfoList = objBizCommentInfo.GetListCache("", TimeSpan.FromSeconds(10), "ObjectId='" + articleId + "' AND IsRelease=1 AND CommentId<" + commentID, "CommentId desc", "top " + loadCount + " *");
                }
            }
            else
            {
                objCommentInfoList = objBizCommentInfo.GetListCache("", TimeSpan.FromSeconds(10), "ObjectId='" + articleId + "' AND IsRelease=1", "CommentId desc", "top " + loadCount + " *");
                recordCount = objBizCommentInfo.GetTotalCache("", TimeSpan.FromSeconds(10), "ObjectId='" + articleId + "' AND IsRelease=1");
            }
            if (objCommentInfoList.IsNull())
            {
                objInvokeResult.ResultCode = "CommentNull";
                objInvokeResult.ResultMessage = "没有更多评论了";
                return objInvokeResult;
            }
            if (isLoadFloor.HasValue && isLoadFloor.Value == 1)
            {
                LoadCommentFloorList(objCommentInfoList, categoryId.Value);
            }
            objInvokeResult.Data = new { CommentList = objCommentInfoList, RecordCount = recordCount };
            return objInvokeResult;
        }

        /// <summary>
        /// 获取热门评论
        /// </summary>
        /// <param name="categoryId"></param>
        /// <param name="articleId"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="isLoadFloor"></param>
        /// <returns></returns>
        public virtual InvokeResult GetCommentHotList(int? categoryId, int? articleId, int? pageIndex = 1, int? pageSize = 10, int? isLoadFloor = 0)
        {
            InvokeResult objInvokeResult = new InvokeResult();
            if (!categoryId.HasValue)
            {
                objInvokeResult.ResultCode = "CategoryIdEmpty";
                objInvokeResult.ResultMessage = "CategoryId不存在";
                return objInvokeResult;
            }
            if (!articleId.HasValue)
            {
                objInvokeResult.ResultCode = "ArticleIdNull";
                objInvokeResult.ResultMessage = "文章编号不存在";
                return objInvokeResult;
            }
            if (!ExistTableCommentInfo(categoryId.Value))
            {
                objInvokeResult.ResultCode = "TableEmpty";
                objInvokeResult.ResultMessage = "评论表不存在";
                return objInvokeResult;
            }
            if (!pageIndex.HasValue || pageIndex <= 0)
            {
                pageIndex = 1;
            }
            if (!pageSize.HasValue || pageSize <= 0 || pageSize > 20)
            {
                pageSize = 10;
            }
            BizCommentInfo objBizCommentInfo = new BizCommentInfo(categoryId.Value.ToString());
            List<CommentInfo> objCommentInfoList = objBizCommentInfo.GetPageListCache("", TimeSpan.FromSeconds(10), pageIndex.Value - 1, 5, "ObjectId=@ObjectId AND ReplyId=0", new { ObjectId = articleId }, "DiggCount desc");
            if (objCommentInfoList.IsNull())
            {
                objInvokeResult.ResultCode = "CommentHotNull";
                objInvokeResult.ResultMessage = "没有热门评论了";
                return objInvokeResult;
            }
            if (isLoadFloor.HasValue && isLoadFloor.Value == 1)
            {
                LoadCommentFloorList(objCommentInfoList, categoryId.Value);
            }
            objInvokeResult.Data = objCommentInfoList;
            return objInvokeResult;
        }

        /// <summary>
        /// 获取评论列表
        /// </summary>
        /// <param name="categoryId"></param>
        /// <param name="articleId"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="isLoadFloor"></param>
        /// <returns></returns>
        public virtual InvokeResult GetCommentPageList(int? categoryId, int? articleId, int? pageIndex = 1, int? pageSize = 10, int? isLoadFloor = 0)
        {
            InvokeResult objInvokeResult = new InvokeResult();
            if (!categoryId.HasValue)
            {
                objInvokeResult.ResultCode = "CategoryIdEmpty";
                objInvokeResult.ResultMessage = "CategoryId不存在";
                return objInvokeResult;
            }
            if (!articleId.HasValue)
            {
                objInvokeResult.ResultCode = "ArticleIdNull";
                objInvokeResult.ResultMessage = "文章编号不存在";
                return objInvokeResult;
            }
            if (!ExistTableCommentInfo(categoryId.Value))
            {
                objInvokeResult.ResultCode = "TableEmpty";
                objInvokeResult.ResultMessage = "评论表不存在";
                return objInvokeResult;
            }
            BizCommentInfo objBizCommentInfo = new BizCommentInfo(categoryId.Value.ToString());
            if (!pageIndex.HasValue || pageIndex <= 0)
            {
                pageIndex = 1;
            }
            if (!pageSize.HasValue || pageSize <= 0 || pageSize > 20)
            {
                pageSize = 10;
            }
            int recordCount = 0;
            List<CommentInfo> objCommentInfoList = objBizCommentInfo.GetPageListCache("", TimeSpan.FromSeconds(10), pageIndex.Value - 1, pageSize.Value, out recordCount, "ObjectId='" + articleId + "' AND IsRelease=1", "CommentId desc");
            if (isLoadFloor.HasValue && isLoadFloor.Value == 1)
            {
                LoadCommentFloorList(objCommentInfoList, categoryId.Value);
            }
            objInvokeResult.Data = new { CommentList = objCommentInfoList, RecordCount = recordCount, PageIndex = pageIndex, PageSize = pageSize, PageCount = (int)Math.Ceiling(((double)recordCount / pageSize.Value)) };
            return objInvokeResult;
        }

        /// <summary>
        /// 展开评论楼层列表
        /// </summary>
        /// <param name="categoryId"></param>
        /// <param name="commentId"></param>
        /// <param name="previousReplyId"></param>
        /// <param name="lastReplyId"></param>
        /// <param name="floorCount"></param>
        /// <returns></returns>
        public virtual InvokeResult GetCommentRestFloorList(int? categoryId, int? commentId, int? previousReplyId, int? lastReplyId, int? floorCount = 50)
        {
            InvokeResult objInvokeResult = new InvokeResult();
            if (!categoryId.HasValue)
            {
                objInvokeResult.ResultCode = "CategoryIdEmpty";
                objInvokeResult.ResultMessage = "CategoryId不存在";
                return objInvokeResult;
            }
            if (!commentId.HasValue)
            {
                objInvokeResult.ResultCode = "CommentIdNull";
                objInvokeResult.ResultMessage = "评论编号不存在";
                return objInvokeResult;
            }
            if (!previousReplyId.HasValue)
            {
                objInvokeResult.ResultCode = "PreviousReplyIdNull";
                objInvokeResult.ResultMessage = "上一条回复编号为空";
                return objInvokeResult;
            }
            if (commentId.Value == previousReplyId.Value)
            {
                objInvokeResult.ResultCode = "CommentIdEqualPreviousReplyId";
                objInvokeResult.ResultMessage = "没有更多回复了";
                return objInvokeResult;
            }
            if (!ExistTableCommentInfo(categoryId.Value))
            {
                objInvokeResult.ResultCode = "TableEmpty";
                objInvokeResult.ResultMessage = "评论表不存在";
                return objInvokeResult;
            }
            BizCommentInfo objBizCommentInfo = new BizCommentInfo(categoryId.Value.ToString());
            CommentInfo objCommentInfo = objBizCommentInfo.GetRecordCache("", commentId.Value, TimeSpan.FromSeconds(10));
            if (objCommentInfo == null)
            {
                objInvokeResult.ResultCode = "CommentInfoNull";
                objInvokeResult.ResultMessage = "评论不存在";
                return objInvokeResult;
            }
            string strReplyId = string.Format(",{0},", previousReplyId.Value);
            string replyIdPath = objCommentInfo.ReplyIdPath;
            if (lastReplyId.HasValue)
            {
                replyIdPath = replyIdPath.Replace("," + lastReplyId + ",", ",");
            }
            if (!replyIdPath.Contains(strReplyId))
            {
                objInvokeResult.ResultCode = "LastReplyNull";
                objInvokeResult.ResultMessage = "上一条回复不存在";
                return objInvokeResult;
            }
            string[] array = replyIdPath.Split(new string[] { strReplyId }, StringSplitOptions.RemoveEmptyEntries);
            if (array == null || array.Length == 1)
            {
                objInvokeResult.ResultCode = "NoMoreReplies";
                objInvokeResult.ResultMessage = "没有更多回复了";
                return objInvokeResult;
            }
            string restReplyIds = null;
            if (!floorCount.HasValue || floorCount.Value <= 0 || floorCount.Value > 50)
            {
                floorCount = 50;
            }
            List<string> listReplyIds = array[1].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            listReplyIds.Remove(commentId.Value.ToString());
            if (listReplyIds.IsNoNull())
            {
                restReplyIds = listReplyIds.Take(floorCount.Value).JoinComma();
            }
            if (restReplyIds.IsNull())
            {
                objInvokeResult.ResultCode = "RestReplyIdsNull";
                objInvokeResult.ResultMessage = "没有更多回复了";
                return objInvokeResult;
            }
            List<CommentInfo> objRestReplyList = objBizCommentInfo.GetListInCache("", TimeSpan.FromSeconds(10), restReplyIds);
            if (objRestReplyList.IsNull())
            {
                objInvokeResult.ResultCode = "NoMoreReplies";
                objInvokeResult.ResultMessage = "没有更多回复了";
                return objInvokeResult;
            }
            objInvokeResult.Data = objRestReplyList;
            return objInvokeResult;
        }

        /// <summary>
        /// 轮询是否有最新评论
        /// </summary>
        /// <param name="categoryId"></param>
        /// <param name="articleId"></param>
        /// <param name="commentId"></param>
        /// <returns></returns>
        public virtual InvokeResult HasCommentLatest(int? categoryId, int? articleId, int? commentId)
        {
            InvokeResult objInvokeResult = new InvokeResult();
            if (!categoryId.HasValue)
            {
                objInvokeResult.ResultCode = "CategoryIdEmpty";
                objInvokeResult.ResultMessage = "CategoryId不存在";
                return objInvokeResult;
            }
            if (!articleId.HasValue)
            {
                objInvokeResult.ResultCode = "ArticleIdNull";
                objInvokeResult.ResultMessage = "文章编号不存在";
                return objInvokeResult;
            }
            if (!ExistTableCommentInfo(categoryId.Value))
            {
                objInvokeResult.ResultCode = "TableEmpty";
                objInvokeResult.ResultMessage = "评论表不存在";
                return objInvokeResult;
            }

            var CurrentCache = TjZheng.Cache.CacheHelper.CacheInstance;
            string cacheKey = string.Format("Article_{0}_LatestComment>{1}", articleId, commentId);
            object obj = CurrentCache.GetCache(cacheKey);
            if (obj == null)
            {
                BizCommentInfo objBizCommentInfo = new BizCommentInfo(categoryId.Value.ToString());
                if (commentId.HasValue)
                {
                    obj = objBizCommentInfo.GetFieldCache<object, CommentInfo, int>("", TimeSpan.FromSeconds(10), "CommentId>@CommentId AND ObjectId=@ObjectId", new { CommentId = commentId, ObjectId = articleId }, "top 1 CommentId");
                }
                else
                {
                    obj = objBizCommentInfo.GetFieldCache<object, CommentInfo, int>("", TimeSpan.FromSeconds(10), "ObjectId=@ObjectId", new { ObjectId = articleId }, "top 1 CommentId");
                }
            }
            if (obj == null)
            {
                objInvokeResult.ResultCode = "HasNoLatest";
                objInvokeResult.ResultMessage = "对不起，没有最新评论";
                return objInvokeResult;
            }
            CurrentCache.SetCache(cacheKey, obj, TimeSpan.FromSeconds(30));
            objInvokeResult.ResultMessage = "有最新的评论";
            return objInvokeResult;
        }

        /// <summary>
        /// 添加评论
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="categoryId"></param>
        /// <param name="articleId"></param>
        /// <param name="replyId"></param>
        /// <param name="userId"></param>
        /// <param name="userName"></param>
        /// <param name="avatar"></param>
        /// <param name="content"></param>
        /// <returns></returns>
        public virtual InvokeResult AddComment(int? parentId, int? categoryId, int? articleId, int? replyId, string userId, string userName, string avatar, string content)
        {
            InvokeResult objInvokeResult = new InvokeResult();
            if (!parentId.HasValue)
            {
                objInvokeResult.ResultCode = "ParentIdEmpty";
                objInvokeResult.ResultMessage = "ParentId不存在";
                return objInvokeResult;
            }
            if (!categoryId.HasValue)
            {
                objInvokeResult.ResultCode = "CategoryIdEmpty";
                objInvokeResult.ResultMessage = "CategoryId不存在";
                return objInvokeResult;
            }
            if (!articleId.HasValue)
            {
                objInvokeResult.ResultCode = "ArticleIdNull";
                objInvokeResult.ResultMessage = "对不起，文章不存在";
                return objInvokeResult;
            }
            if (content.IsNull())
            {
                objInvokeResult.ResultCode = "ContentEmpty";
                objInvokeResult.ResultMessage = "对不起，评论内容不能为空";
                return objInvokeResult;
            }
            if (!ExistTableCommentInfo(categoryId.Value))
            {
                objInvokeResult.ResultCode = "TableEmpty";
                objInvokeResult.ResultMessage = "评论表不存在";
                return objInvokeResult;
            }
            objInvokeResult = HttpContext.Current.Request.Url.AbsoluteUri.CheckUrlUniqueSignature();
            if (objInvokeResult.ResultCode != "Success")
            {
                return objInvokeResult;
            }
            var badwordsList = content.SearchMatchBadWords();
            if (badwordsList.IsNoNull())
            {
                objInvokeResult.ResultCode = "ContentHasBadWords";
                objInvokeResult.ResultMessage = "对不起，评论内容包含敏感信息词汇 " + badwordsList[0];
                return objInvokeResult;
            }

            BizCommentInfo objBizCommentInfo = new BizCommentInfo(categoryId.Value.ToString());
            CommentInfo objRepliedComment = null;
            if (replyId.HasValue)
            {
                objRepliedComment = objBizCommentInfo.GetRecordCache("", replyId.Value, TimeSpan.FromSeconds(10));
                if (objRepliedComment == null)
                {
                    objInvokeResult.ResultCode = "ReplyNull";
                    objInvokeResult.ResultMessage = "对不起，被回复的评论不存在或已删除";
                    return objInvokeResult;
                }
            }

            string signature = HttpContext.Current.Request["signature"];
            var CurrentCache = TjZheng.Cache.CacheHelper.CacheInstance;
            string cacheKey = string.Format("LastComment_{0}_{1}_{2}", signature, articleId, userId);
            //获取上一次评论缓存
            object obj = CurrentCache.GetCache<object>(cacheKey);
            if (obj != null)
            {
                objInvokeResult.ResultCode = "CommentFrequently";
                objInvokeResult.ResultMessage = "对不起，请你与上次评论间隔5秒";
                return objInvokeResult;
            }
            //设置上一条评论缓存
            obj = new object();
            CurrentCache.SetCache(cacheKey, obj, TimeSpan.FromSeconds(5));

            CommentInfo objCommentInfo = new CommentInfo()
            {
                ObjectId = articleId.Value.ToString(),
                ObjectCode = "Article_" + articleId,
                UserId = userId,
                NickName = userName.SetNullToDefaultValue("网友"),
                Content = content,
                IsRelease = 1,
                UserIP = RequestHelper.GetRealIp(),
                //DeviceName=HttpContext
                CreateDate = DateTime.Now,
                ReplyId = objRepliedComment == null ? 0 : objRepliedComment.CommentId,
                Avatar = avatar.SetNullToDefaultValue(string.Empty)
            };

            objInvokeResult.ResultMessage = "评论成功";
            objInvokeResult.Data = objBizCommentInfo.Add(objCommentInfo);
            if (objRepliedComment != null)
            {
                objCommentInfo.ReplyIdPath = objRepliedComment.ReplyIdPath + objCommentInfo.CommentId + ",";
            }
            else
            {
                objCommentInfo.ReplyIdPath = "," + objCommentInfo.CommentId + ",";
            }
            //todo：走xml
            objBizCommentInfo.UpdateAsync("ReplyIdPath=@ReplyIdPath", objCommentInfo.CommentId, new { ReplyIdPath = objCommentInfo.ReplyIdPath });

            //更新文章的评论数
            BizBase objBizBase = new BizBase();
            objBizBase.ExecuteNonQueryAsync("TjZheng_News", "ApiGroup_News", "TjZheng_IncreaseCount_Article", new { ArticleId = articleId, CollectId = string.Format("{0}-{1}", categoryId, articleId) }, new { ParentId = parentId, CategoryId = categoryId, RelatedCount = "CommentCount", Increase = 1 });
            return objInvokeResult;
        }

        /// <summary>
        /// 评论点赞
        /// </summary>
        /// <param name="categoryId"></param>
        /// <param name="commentId"></param>
        /// <returns></returns>
        public virtual InvokeResult DiggComment(int? categoryId, int? commentId)
        {
            InvokeResult objInvokeResult = new InvokeResult();
            if (!commentId.HasValue)
            {
                objInvokeResult.ResultCode = "ArticleIdNull";
                objInvokeResult.ResultMessage = "对不起，评论编号不存在";
                return objInvokeResult;
            }
            if (!ExistTableCommentInfo(categoryId.Value))
            {
                objInvokeResult.ResultCode = "TableEmpty";
                objInvokeResult.ResultMessage = "评论表不存在";
                return objInvokeResult;
            }

            objInvokeResult = HttpContext.Current.Request.Url.AbsoluteUri.CheckUrlUniqueSignature();
            if (objInvokeResult.ResultCode != "Success")
            {
                return objInvokeResult;
            }
            string signature = HttpContext.Current.Request["signature"];
            var CurrentCache = TjZheng.Cache.CacheHelper.CacheInstance;
            string cacheKey = string.Format("LastDiggComment_{0}_{1}", signature, commentId);
            //获取上一次点赞次数
            var objLastDigg = CurrentCache.GetCache(cacheKey).CreateValueDictionary();
            object obj = null;
            int diggCount = 0;
            if (objLastDigg.IsNoNull() && objLastDigg.TryGetValue("DiggCount", out obj))
            {
                diggCount = Convert.ToInt32(obj);
                if (objLastDigg.TryGetValue("DiggTime", out obj))
                {
                    DateTime diggTime = Convert.ToDateTime(obj);
                    if (diggCount >= 5 && diggTime.AddSeconds(5).IsGreaterThanCurrent())
                    {
                        objInvokeResult.ResultCode = "DiggCommentFrequently";
                        objInvokeResult.ResultMessage = "对不起，你点赞的频率过快";
                        return objInvokeResult;
                    }
                    diggCount++;
                    //设置上一次点赞缓存
                    CurrentCache.SetCache(cacheKey, new { DiggCount = diggCount, DiggTime = diggTime }, TimeSpan.FromSeconds(5));
                }

            }
            else
            {
                diggCount++;
                //设置上一次点赞缓存
                CurrentCache.SetCache(cacheKey, new { DiggCount = diggCount, DiggTime = DateTime.Now }, TimeSpan.FromSeconds(5));
            }

            //更新评论点赞
            BizCommentInfo objBizCommentInfo = new BizCommentInfo(categoryId.Value.ToString());
            objBizCommentInfo.Update("DiggCount=DiggCount+1", commentId.Value);

            objInvokeResult.ResultMessage = "点赞成功";
            return objInvokeResult;
        }

        /// <summary>
        /// 加载评论回复列表
        /// </summary>
        /// <param name="objList"></param>
        /// <param name="categoryId"></param>
        /// <param name="floorCount"></param>
        public virtual void LoadCommentFloorList(List<CommentInfo> objList, int categoryId, int? floorCount = 3)
        {
            if (objList.IsNull())
            {
                return;
            }
            if (!floorCount.HasValue || floorCount.Value <= 0 || floorCount.Value > 20)
            {
                floorCount = 3;
            }

            List<string> objFloorIds = new List<string>();
            List<string> strFloorIds;
            foreach (CommentInfo objCommentInfo in objList)
            {
                if (objCommentInfo.ReplyId == 0)
                {
                    continue;
                }
                strFloorIds = objCommentInfo.ReplyIdPath.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                //移除最后一个
                strFloorIds.Remove(objCommentInfo.CommentId.ToString());
                //添加倒数第二个（移除后是最后一个）
                objFloorIds.Add(objFloorIds.Last());
                //添加前floorCount-1楼层
                objFloorIds.AddRange(strFloorIds.Take(floorCount.Value - 1));
            }
            if (objFloorIds.IsNoNull())
            {
                CommentInfo objCommentInfoExist = null;
                objFloorIds = objFloorIds.Distinct().ToList();//Id排重
                List<CommentInfo> objFloorList = new List<CommentInfo>();
                int floorIdCount = objFloorIds.Count;
                for (int i = floorIdCount - 1; i >= 0; i--)
                {
                    objCommentInfoExist = objList.FirstOrDefault(c => string.Equals(objFloorIds[i], c.CommentId.ToString()));
                    if (objCommentInfoExist != null)
                    {
                        //若现有评论已有回复的评论，从内存取
                        //数据库和CPU性能 两者选一
                        objFloorList.Add(objCommentInfoExist.JsonSerialize().JsonDeserialize<CommentInfo>());
                        objFloorIds.Remove(objFloorIds[i]);
                    }
                }
                if (objFloorIds.IsNoNull())
                {
                    BizCommentInfo objBizCommentInfo = new BizCommentInfo(categoryId.ToString());
                    //剩下的回复读数据库
                    List<CommentInfo> objRest = objBizCommentInfo.GetListInCache("", TimeSpan.FromSeconds(10), objFloorIds.JoinComma());
                    if (objRest.IsNoNull())
                    {
                        objFloorList.AddRange(objRest);
                    }
                }
                foreach (CommentInfo objCommentInfo in objList)
                {
                    if (objCommentInfo.ReplyId == 0)
                    {
                        continue;
                    }
                    //组织评论回复
                    objCommentInfo.FloorList = objFloorList.Where(c => objCommentInfo.ReplyIdPath.Contains(string.Format(",{0},", c.CommentId))).OrderBy(c => c.CommentId).ToList();
                }
            }
        }
    }
}
